package tool

import (
	"bytes"
	"crypto/md5"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"math/rand"
	"net/http"
	"net/url"
	"strconv"
	"time"
)

type UidObj struct {
	GameUid string `json:"game_uid"`
	GameBiz string `json:"game_biz"`
	Region  string `json:"region"`
}

func GetUidList(cookis string) ([]UidObj, string, error) {
	reqToken, _ := http.NewRequest("GET", "https://webapi.account.mihoyo.com/Api/login_by_cookie", nil)
	reqToken.Header.Add("Cookie", cookis)
	resToken, err := http.DefaultClient.Do(reqToken)
	if err != nil {
		return []UidObj{}, "", err
	}
	bodyToken, err := ioutil.ReadAll(resToken.Body)
	if err != nil {
		return nil, "", err
	}
	type accountInfo struct {
		AccountId     int    `json:"account_id"`
		WebLoginToken string `json:"weblogin_token"`
	}
	type accountData struct {
		AccountInfo accountInfo `json:"account_info"`
	}
	type ReqTokenData struct {
		Data accountData `json:"data"`
	}
	tokenData := ReqTokenData{}
	json.Unmarshal(bodyToken, &tokenData)
	if tokenData.Data.AccountInfo.WebLoginToken == "" {
		return []UidObj{}, "", errors.New("登录信息已失效")
	}
	uid := strconv.Itoa(tokenData.Data.AccountInfo.AccountId)
	token := tokenData.Data.AccountInfo.WebLoginToken
	fmt.Println(string(bodyToken))
	//获取tid
	reqTid, _ := http.NewRequest("GET", "https://api-takumi.mihoyo.com/auth/api/getMultiTokenByLoginTicket?login_ticket="+token+"&token_types=3&uid="+uid, nil)
	reqTid.Header.Add("Cookie", cookis)
	resTid, err := http.DefaultClient.Do(reqTid)
	if err != nil {
		return []UidObj{}, "", err
	}
	bodyTid, err := ioutil.ReadAll(resTid.Body)
	if err != nil {
		return []UidObj{}, "", err
	}

	type tidObj struct {
		Name  string `json:"name"`
		Token string `json:"token"`
	}
	type tidList struct {
		List []tidObj `json:"list"`
	}
	type ReqTidData struct {
		Data tidList `json:"data"`
	}
	tidData := ReqTidData{}
	err = json.Unmarshal(bodyTid, &tidData)
	if err != nil {
		return []UidObj{}, "", err
	}
	var newcookie = "stuid=" + uid + ";"
	for i := range tidData.Data.List {
		newcookie += tidData.Data.List[i].Name + "=" + tidData.Data.List[i].Token + ";"
	}
	//fmt.Println(newcookie)
	newcookie += cookis

	//获取uid
	reqUid, _ := http.NewRequest("GET", "https://api-takumi.mihoyo.com/binding/api/getUserGameRolesByCookie?game_biz=hk4e_cn",
		nil)
	reqUid.Header.Add("Cookie", newcookie)
	resUid, err := http.DefaultClient.Do(reqUid)
	if err != nil {
		return []UidObj{}, "", err
	}
	bodyUid, _ := ioutil.ReadAll(resUid.Body)

	type UidList struct {
		List []UidObj `json:"list"`
	}
	type ReqUidData struct {
		Data UidList `json:"data"`
	}
	uidData := ReqUidData{}
	err = json.Unmarshal(bodyUid, &uidData)
	if err != nil {
		return []UidObj{}, "", err
	}
	fmt.Println(uidData)
	return uidData.Data.List, newcookie, nil
}

func GetJsonUrl(game_uid string, game_biz string, region string, newcookie string) (string, error) {

	// 获取key
	type AuthKeyPostData struct {
		AuthAppid string `json:"auth_appid"`
		GameBiz   string `json:"game_biz"`
		GameUid   string `json:"game_uid"`
		Region    string `json:"region"`
	}
	payloadObj := AuthKeyPostData{
		"webview_gacha", game_biz, game_uid, region,
	}
	payload, err := json.Marshal(payloadObj)
	if err != nil {
		return "", err
	}
	req2, err := http.NewRequest("POST", "https://api-takumi.mihoyo.com/binding/api/genAuthKey",
		bytes.NewReader(payload))
	if err != nil {
		return "", err
	}
	req2.Header.Add("Content-Type", "application/json;charset=utf-8")
	req2.Header.Add("Host", "api-takumi.mihoyo.com")
	req2.Header.Add("Accept", "application/json, text/plain, */*")
	req2.Header.Add("x-rpc-app_version", "2.28.1")
	req2.Header.Add("x-rpc-client_type", "5")
	req2.Header.Add("x-rpc-device_id", "CBEC8312-AA77-489E-AE8A-8D498DE24E90")
	req2.Header.Add("DS", getDs())
	req2.Header.Add("Cookie", newcookie)

	res2, err := http.DefaultClient.Do(req2)
	if err != nil {
		return "", err
	}
	body2, err := ioutil.ReadAll(res2.Body)
	if err != nil {
		return "", err
	}
	type authkey struct {
		AuthKey string `json:"authkey"`
	}
	type ReqAuthData struct {
		Data authkey `json:"data"`
	}

	authData := ReqAuthData{}
	err = json.Unmarshal(body2, &authData)
	if err != nil {
		return "", err
	}
	escape := url.QueryEscape(authData.Data.AuthKey)
	//fmt.Println(escape)

	// 获取最终的链接
	url := "https://hk4e-api.mihoyo.com/event/gacha_info/api/getGachaLog?"
	url += "win_mode=fullscreen&authkey_ver=1&sign_type=2&auth_appid=webview_gacha&init_type=301&gacha_id=b4ac24d133739b7b1d55173f30ccf980e0b73fc1"
	url += "&lang=zh-cn&device_type=mobile&game_version=CNRELiOS3.0.0_R10283122_S10446836_D10316937&plat_type=ios"
	url += "&game_biz=" + game_biz + "&size=20&authkey=" + escape + "&region=" + region + "&timestamp=1664481732&page=1&end_id="
	return url, nil
}

func getDs() string {
	salt := "ulInCDohgEs557j0VsPDYnQaaz6KJcv5"
	time1 := strconv.FormatInt(time.Now().Unix(), 10)
	str := getStr()
	key := "salt=" + salt + "&t=" + time1 + "&r=" + str
	md51 := toMD5(key)

	fmt.Println()

	return string(time1) + "," + str + "," + md51
}
func getStr() string {
	chars := []rune("ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678")
	b := make([]rune, 6)
	for i := range b {
		b[i] = chars[rand.Intn(len(chars))]
	}
	return string(b)
}

func toMD5(code string) string {
	MD5 := md5.New()
	_, _ = io.WriteString(MD5, code)
	return hex.EncodeToString(MD5.Sum(nil))
}
